/**
 * 任务流程管理框架 - TaskFlow
 * 功能：支持同步/异步任务串联、流程暂停/恢复/强制结束、全生命周期钩子
 * 用法：new TaskFlow(config).start()
 */
export default class TaskFlow {
  /**
   * 构造函数初始化流程配置
   * @param {Object} config 流程配置项
   * @param {Array} config.tasks 任务列表，每项需包含 {type: 'sync'|'async', handler: Function}
   * @param {Function} [config.onStart] 流程开始钩子
   * @param {Function} [config.onPause] 流程暂停钩子
   * @param {Function} [config.onResume] 流程恢复钩子
   * @param {Function} [config.onForceStop] 流程强制结束钩子
   * @param {Function} [config.onTaskFail] 单个任务失败钩子 (err, taskIndex) => {}
   * @param {Function} [config.onComplete] 流程正常完成钩子 (result) => {}
   */
  constructor(config) {
    // 循环绑定每个方法到当前实例
    config.tasks = config.tasks.map((task) => {
      const method = task.handler
      // 确保是函数才进行绑定
      return {
        ...task,
        handler: typeof method === 'function' ? method.bind(this) : method
      }
    })
    // 绑定每个钩子方法到当前实例
    for (const key in config) {
      const method = config[key]
      if (typeof method === 'function') {
        config[key] = method.bind(this)
      }
    }

    // 基础配置初始化
    this.baseConfig = {
      tasks: [],
      logs: [],
      onStart: () => {},
      onBefore: () => {},
      onPause: () => {},
      onResume: () => {},
      onForceStop: () => {},
      onTaskFail: (err) => console.error('任务失败:', err),
      onComplete: (res) => console.log('流程完成:', res),
      onEnd: () => {}
    }
    // 合并用户配置与基础配置
    this.config = Object.assign({}, this.baseConfig, config)
    // 初始化参数
    this.initialization()
  }

  /**
   * 初始化参数
   */
  initialization() {
    // 流程状态管理
    this.state = {
      isRunning: false, // 是否运行中
      isPaused: false, // 是否暂停中
      isForceStopped: false, // 是否被强制停止
      currentTaskIndex: 0, // 当前执行任务索引
      taskResults: [] // 所有任务执行结果缓存
    }
  }

  /**
   * 核心方法：执行下一个任务
   * 自动处理同步/异步任务差异，响应暂停/强制结束状态
   */
  async executeNextTask() {
    // 终止条件：流程暂停
    if (this.state.isPaused) {
      return
    } else if (!this.state.isRunning || this.state.currentTaskIndex >= this.config.tasks.length) {
      // 强制结束/任务全部完成
      // 任务全部完成时触发结束钩子
      if (this.state.currentTaskIndex >= this.config.tasks.length && this.state.isRunning) {
        this.state.isRunning = false
        this.config.onComplete(this.state.taskResults)
      }
      this.config.onEnd()
      return
    }

    // 获取当前任务
    const currentIndex = this.state.currentTaskIndex
    const currentTask = this.config.tasks[currentIndex]
    this.config.onBefore(currentTask)
    try {
      let taskResult
      // 区分同步/异步任务执行逻辑
      if (currentTask.type === 'sync') {
        // 同步任务：直接执行
        taskResult = currentTask.handler(
            this.state.taskResults, // 传入历史结果
            currentIndex // 传入当前任务索引
        )
      } else if (currentTask.type === 'async') {
        // 异步任务：等待Promise完成
        taskResult = await currentTask.handler(this.state.taskResults, currentIndex)
      } else {
        throw new Error(`任务${currentIndex}类型错误，仅支持 sync/async`)
      }

      // 任务成功：缓存结果，执行下一个
      this.state.taskResults.push(taskResult)
      this.state.currentTaskIndex++
      this.executeNextTask() // 递归执行下一个任务
    } catch (err) {
      // 任务失败：触发失败钩子，终止流程
      this.state.isRunning = false
      this.config.onTaskFail(err, currentTask)
      this.config.onEnd()
    }
  }

  /**
   * 流程启动方法
   * 仅当流程未运行时可调用
   */
  start() {
    if (this.state.isRunning) {
      console.warn('流程已在运行中，无需重复启动')
      return
    }

    // 初始化流程状态
    this.state.isRunning = true
    this.state.isPaused = false
    this.state.currentTaskIndex = 0
    this.state.taskResults = []

    // 触发启动钩子，开始执行第一个任务
    this.config.onStart(this)
    this.executeNextTask()
  }

  /**
   * 流程暂停方法
   * 仅当流程运行中且未暂停时可调用
   */
  pause() {
    if (!this.state.isRunning || this.state.isPaused) {
      console.warn('流程未运行或已暂停，无法执行暂停')
      return
    }

    this.state.isPaused = true
    this.config.onPause()
  }

  /**
   * 流程恢复方法
   * 仅当流程暂停时可调用
   */
  resume() {
    if (!this.state.isRunning || !this.state.isPaused) {
      console.warn('流程未运行或未暂停，无法执行恢复')
      return
    }

    this.state.isPaused = false
    this.config.onResume()
    this.executeNextTask() // 从暂停处继续执行
  }

  /**
   * 流程强制结束方法
   * 无论当前状态如何，强制终止流程
   */
  forceStop() {
    if (!this.state.isRunning) {
      console.warn('流程未运行，无需强制结束')
      return
    }
    this.state.isRunning = false
    this.state.isForceStopped = true
    this.config.onForceStop()
    if (this.state.isPaused) {
      this.state.isPaused = false
      this.config.onEnd()
    }
  }
}
